home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / seyon / SeSig.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  5KB  |  169 lines

  1.  
  2. /*
  3.  * This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M.
  4.  * Saggaf. All rights reserved.
  5.  *
  6.  * See the file COPYING (1-COPYING) or the manual page seyon(1) for a full
  7.  * statement of rights and permissions for this program.
  8.  */
  9.  
  10. /*
  11.  * signals -
  12.  *    An Xt Intrinsics signal handler developed based on discussions
  13.  *    in comp.windows.x and written by someone who wishes to be
  14.  *    anonymous. [Modified by me -- M.S.]
  15.  *
  16.  *    A pipe is created and the read side is passed off to
  17.  *    XtAppAddInput().  Everytime a signal occurs a byte, indicating
  18.  *    which signal, is written by the signal handler on the write
  19.  *    side of the pipe.  This causes the Intrinsics to call the
  20.  *    input handler which then invokes the correct callback.
  21.  *
  22.  *    The potential for deadlock exists if the pipe is ever filled!
  23.  *
  24.  * $Id: signals.c,v 1.1 92/12/10 08:51:01 ware Exp $
  25.  * $Log:    signals.c,v $
  26.  * Revision 1.1  92/12/10  08:51:01  ware
  27.  * Initial revision
  28.  *
  29.  */
  30.  
  31. #include <X11/Intrinsic.h>
  32. #include <signal.h>        /* signal stuff */
  33. #include <unistd.h>
  34. #include <sys/types.h>        /* for pipe */
  35. #include <string.h>        /* for memset */
  36. #include "SeSig.h"
  37.  
  38. #if __STDC__ == 1
  39. #if defined(SVR4)
  40. /*
  41.  * This is a hack. On the system V release 4 unix, NSIG *is* defined
  42.  * but it NOT defined if the compiler is in ANSI mode. Presumably the
  43.  * use of this symbol should be avoided.
  44.  */
  45. #ifndef NSIG
  46. #define NSIG (SIGXFSZ+1)
  47. #endif
  48. #endif
  49. #endif
  50.  
  51. static _XoSignalData sig_info[NSIG + 1];    /* NSIG is max signal value */
  52.  
  53. static int      pipefd[2];    /* the input & output pipes */
  54.  
  55. static void     _xsig_handler(
  56. #if NeedFunctionPrototypes
  57.                    int sig,
  58.                    int code
  59. #endif
  60. );
  61.  
  62. static void
  63.                 _xsig_pipe_handler(
  64. #if NeedFunctionPrototypes
  65.                     XtPointer client_data,
  66.                     int *source,
  67.                     XtInputId * id
  68. #endif
  69. );
  70.  
  71. /*
  72.  * XoAppAddSignal -
  73.  *    Install a handler for a particular signal.  There can be only
  74.  *    a single handler per signal (it might be nice to use a callback).
  75.  */
  76.  
  77. XoSignalCallbackProc
  78. XoAppAddSignal(context, sig, handler, client_data)
  79.      XtAppContext    context;    /* application context */
  80.      int             sig;    /* which signal */
  81.      XoSignalCallbackProc handler;    /* the handler */
  82.      XtPointer       client_data;    /* private data */
  83. {
  84.   static int      firsttime = True;
  85.  
  86.   /*
  87.      * We need to create the pipe and tell the intrinsics about
  88.      * the new file descriptor
  89.      */
  90.   if (firsttime) {
  91.     firsttime = False;
  92.     pipe(pipefd);
  93.     XtAppAddInput(context, pipefd[0],
  94.           (XtPointer) XtInputReadMask,
  95.           _xsig_pipe_handler, (XtPointer) NULL);
  96.   }
  97.   sig_info[sig].handler = handler;
  98.   sig_info[sig].client_data = client_data;
  99.   return (XoSignalCallbackProc)signal(sig, (void (*)())_xsig_handler);
  100. }                /* XoAppAddSignal */
  101.  
  102. /*
  103.  * XoAppRemoveSignal -
  104.  *    Uninstalls a handler for a particular signal.  The values
  105.  *    of handler and client_data most match in order to remove the
  106.  *    particular signal handler.  If there are no more remaining
  107.  *    signal handlers for that signal then SIG_DFL is installed.
  108.  *
  109.  *    Of course, the current implementation only allows one handler
  110.  *    per signal but in the future when multiple ones are added this
  111.  *    will continue to work.  The application context is not used
  112.  *    and is left merely for consistency.
  113.  */
  114.  
  115. void
  116. XoAppRemoveSignal(context, sig)
  117.      XtAppContext    context;    /* application context */
  118.      int             sig;    /* which signal */
  119. {
  120.   signal(sig, SIG_DFL);           /* restore old signal handler */
  121.   sig_info[sig].handler = (XoSignalCallbackProc) NULL;
  122.   sig_info[sig].client_data = NULL;
  123. }                /* XoAppRemoveSignal */
  124.  
  125. void
  126. XoAppIgnoreSignal(context, sig)
  127.      XtAppContext    context;    /* application context */
  128.      int             sig;    /* which signal */
  129. {
  130.   signal(sig, SIG_IGN);           /* ignore signal */
  131.   sig_info[sig].handler = (XoSignalCallbackProc) NULL;
  132.   sig_info[sig].client_data = NULL;
  133. }                /* XoAppIgnoreSignal */
  134.  
  135. /*
  136.  * _xsig_handler -
  137.  *    the actual signal handler (custom), writes a byte to a pipe
  138.  */
  139. static void
  140. _xsig_handler(sig, code)
  141.      int             sig;
  142.      int             code;
  143. {
  144.   char            sig_value;
  145.  
  146.   sig_value = sig;
  147.   write(pipefd[1], &sig_value, 1);
  148. }                /* _xsig_handler */
  149.  
  150. /*
  151.  * _xsig_pipe_handler -
  152.  *    reads input from the pipe and executes the corresponding callback.
  153.  */
  154.  
  155. static void
  156. _xsig_pipe_handler(client_data, source, id)
  157.      XtPointer       client_data;
  158.      int            *source;
  159.      XtInputId      *id;
  160. {
  161.   unsigned char   sig_value;
  162.   int             sig;
  163.  
  164.   read(pipefd[0], &sig_value, 1);
  165.   sig = sig_value;
  166.   if (sig > 0 && sig < NSIG && sig_info[sig].handler)
  167.     (*sig_info[sig].handler) (sig, sig_info[sig].client_data);
  168. }                /* _xsig_pipe_handler */
  169.